/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.app.module.partner.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.yanlight.app.dal.dao.OrderDAO;
import com.yanlight.app.dal.dao.PaycodeDAO;
import com.yanlight.app.dal.dao.UserDAO;
import com.yanlight.app.dal.dto.OrderQuery;
import com.yanlight.app.dal.entity.Admin;
import com.yanlight.app.dal.entity.Order;
import com.yanlight.app.dal.entity.PayCode;
import com.yanlight.app.module.partner.model.PartnOrderSpec;
import com.yanlight.app.module.partner.request.PartnOrderRequest;
import com.yanlight.app.module.partner.response.PartnOrderListResponse;
import com.yanlight.app.module.partner.service.PartnOrderService;
import com.yanlight.support.ServletContextSupport;
import com.yanlight.type.BooleanType;
import com.yanlight.type.OrderSceneType;
import com.yanlight.type.OrderType;
import com.yanlight.type.PayType;

/**
 * 
 * @author haolw
 * @time 2018/07/23
 */
@Service
public class PartnOrderServiceImpl implements PartnOrderService {
	@Autowired
	private OrderDAO orderDAO;
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private PaycodeDAO paycodeDAO;

	@Override
	public PartnOrderListResponse findPage(PartnOrderRequest request) {
		Integer userId = request.getUserId();
		Integer sceneType = request.getSceneType();
		String subEmail = request.getSubEmail();
		String payCodeAlias = request.getCodeAlias();
		Admin admin = userDAO.findById(userId);
		PartnOrderListResponse response = new PartnOrderListResponse();
		response.setPageSize(request.getPageSize());
		response.setTotalRecord(0);

		OrderQuery condition = new OrderQuery();
		BeanUtils.copyProperties(request, condition);
		condition.setStatus(OrderType.PAYMENTED.getType());
		if (sceneType != null) {
			condition.addScene(sceneType);
		} else {
			condition.setScenes(OrderSceneType.getMasterOffType());
		}
		condition.addCompanyId(admin.getCompanyId());

		Map<Integer, Admin> operatorsMap = new HashMap<Integer, Admin>();
		if (StringUtils.isNotBlank(subEmail)) {
			List<Admin> fuzzyList = userDAO.findByFuzzyEmail(subEmail);
			if (!CollectionUtils.isEmpty(fuzzyList)) {
				for (Admin fuzzy : fuzzyList) {
					condition.addOperationId(fuzzy.getId());
					operatorsMap.put(fuzzy.getId(), fuzzy);
				}
			} else {
				condition.addOperationId(-1);
			}
		}

		Map<Integer, PayCode> paycodesMap = new HashMap<Integer, PayCode>();
		if (StringUtils.isNotBlank(payCodeAlias)) {
			List<PayCode> payCodeList = paycodeDAO.findListByAlias(payCodeAlias);
			if (!CollectionUtils.isEmpty(payCodeList)) {
				for (PayCode payCode : payCodeList) {
					condition.addPayCodeId(payCode.getId());
					paycodesMap.put(payCode.getId(), payCode);
				}
			} else {
				condition.addPayCodeId(-1);
			}
		}

		int count = orderDAO.count(condition);
		if (count > 0) {
			List<Order> orders = orderDAO.findList(condition);

			if (StringUtils.isBlank(subEmail)) {
				List<Integer> operationIds = new ArrayList<Integer>();
				for (Order order : orders) {
					Integer operationId = order.getOperationId();
					if (operationId != null) {
						operationIds.add(operationId);
					}
				}
				if (!CollectionUtils.isEmpty(operationIds)) {
					List<Admin> operators = userDAO.findByIds(operationIds);
					if (!CollectionUtils.isEmpty(operators)) {
						for (Admin operator : operators) {
							operatorsMap.put(operator.getId(), operator);
						}
					}
				}
			}

			if (StringUtils.isBlank(payCodeAlias)) {
				List<Integer> paycodeIds = new ArrayList<Integer>();
				for (Order order : orders) {
					Integer payCodeId = order.getPayCodeId();
					if (payCodeId != null) {
						paycodeIds.add(payCodeId);
					}
				}
				if (!CollectionUtils.isEmpty(paycodeIds)) {
					List<PayCode> payCodeList = paycodeDAO.findByIds(paycodeIds);
					for (PayCode payCode : payCodeList) {
						paycodesMap.put(payCode.getId(), payCode);
					}
				}
			}

			PartnOrderSpec spec;
			for (Order item : orders) {
				spec = new PartnOrderSpec();
				BeanUtils.copyProperties(item, spec);
				Integer operationId = item.getOperationId();
				Admin operator = operatorsMap.get(operationId);
				if (operator != null) {
					spec.setSubAccountEmail(operator.getEmail());
				}
				PayCode payCode = paycodesMap.get(item.getPayCodeId());
				if (payCode != null) {
					spec.setCodeAlias(payCode.getAlias());
				}
				response.addOrder(spec);
			}
		}
		response.setTotalRecord(count);
		return response;
	}

	@Override
	public void export(OutputStream outputStream, PartnOrderRequest request) {
		request.setPage(BooleanType.FALSE.ordinal());
		PartnOrderListResponse pageList = findPage(request);
		String templatePath = "/WEB-INF/excel_template/order_template.xlsx";
		File file = ServletContextSupport.getContextFile(templatePath);
		InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(file);
			XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
			XSSFSheet sheet = workbook.getSheetAt(0);
			int count = pageList.getOrders().size();
			XSSFCellStyle cellStyle = workbook.createCellStyle();
			cellStyle.setAlignment(HorizontalAlignment.CENTER);
			for (int i = 0; i < count; i++) {
				PartnOrderSpec orderSpec = pageList.getOrders().get(i);
				XSSFRow xssfRow = sheet.createRow(i + 1);
				XSSFCell xssfCell = xssfRow.createCell(0, CellType.NUMERIC);
				xssfCell.setCellValue(i + 1);
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(1, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getSn());
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(2, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getTransactionNo());
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(3, CellType.STRING);
				xssfCell.setCellValue(OrderSceneType.getNameByType(orderSpec.getScene()));
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(4, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getCodeAlias());
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(5, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getSubAccountEmail());
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(6, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getPayTime());
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(7, CellType.STRING);
				xssfCell.setCellValue(PayType.getNameByType(orderSpec.getPayType()));
				xssfCell.setCellStyle(cellStyle);
				xssfCell = xssfRow.createCell(8, CellType.STRING);
				xssfCell.setCellValue(orderSpec.getTotalFee());
				xssfCell.setCellStyle(cellStyle);

			}
			workbook.write(outputStream);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				inputStream.close();
				outputStream.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return;
	}

}
